﻿#include "MutiVTKFilesReader.h"
#include <fstream>
#include <vtkPointSet.h>
#include <vtkPolyData.h>
#include <vtkUnstructuredGrid.h>
#include <vtksys/SystemTools.hxx>
#include <vtkPolyDataReader.h>
#include <vtkUnstructuredGridReader.h>
#include <vtkStructuredGridReader.h>
#include <vtkStructuredGrid.h>
#include <QDebug>
#include "CommonFunction.h"

namespace pst
{
    MutiVTKFilesReader::MutiVTKFilesReader()
        : m_fileName{}
        , m_polyDataReader(vtkPolyDataReader::New())
        , m_unstructuredGridReader(vtkUnstructuredGridReader::New())
        , m_structuredGridReader(vtkStructuredGridReader::New())
        , m_fileType{}
        , m_outputData(nullptr)
    {
    }

    MutiVTKFilesReader::~MutiVTKFilesReader()
    {
        m_polyDataReader->Delete();
        m_unstructuredGridReader->Delete();
        m_structuredGridReader->Delete();
    }

    void MutiVTKFilesReader::SetFileName(const QString& fileName)
    {
        m_fileName = fileName;
    }

    bool MutiVTKFilesReader::Update(QString& errorMess)
    {
        if (!vtksys::SystemTools::FileExists(m_fileName.toStdString(), true))
        {
            errorMess = QString::fromUtf8(" File read fail! File name is ") + m_fileName;
            return false;
        }

        auto type = CheckDataInnerType();
        switch (type)
        {
        case DataType::POLYDATA:
            m_polyDataReader->SetFileName(m_fileName.toStdString().c_str());
            try
            {
                m_polyDataReader->Update();
            }
            catch (const std::exception& e)
            {
                errorMess = e.what();
                return false;
            }
            m_fileType = "vtkPolyData";
            m_outputData = m_polyDataReader->GetOutput();
            return true;
            break;

        case DataType::UNSTRUCTEDGRID:
            m_unstructuredGridReader->SetFileName(m_fileName.toStdString().c_str());
            m_unstructuredGridReader->ReadAllVectorsOn();
            m_unstructuredGridReader->ReadAllScalarsOn();
            m_unstructuredGridReader->ReadAllFieldsOn();
            try
            {
                m_unstructuredGridReader->Update();
            }
            catch (const std::exception& e)
            {
                errorMess = e.what();
                return false;
            }
            m_fileType = "vtkUnstructuredGrid";
            m_outputData = m_unstructuredGridReader->GetOutput();
            return true;
            break;

        case DataType::STRUCTEDGRID:
            m_structuredGridReader->SetFileName(m_fileName.toStdString().c_str());
            m_structuredGridReader->ReadAllVectorsOn();
            m_structuredGridReader->ReadAllScalarsOn();
            m_structuredGridReader->ReadAllFieldsOn();
            try
            {
                m_structuredGridReader->Update();
            }
            catch (const std::exception& e)
            {
                errorMess = e.what();
                return false;
            }
            m_fileType = "vtkStructuredGrid";
            m_outputData = m_structuredGridReader->GetOutput();
            return true;
            break;
        case DataType::UNKNOWN:
            m_fileType = "UNKNOWN";
            errorMess = "Unkown file type";
            return false;
            break;
        }
        return true;
    }

    vtkPointSet* MutiVTKFilesReader::GetOutput()
    {
        return m_outputData;
    }

    QString MutiVTKFilesReader::GetFileInnerTypeAsStrng()
    {
        return m_fileType;
    }

    MutiVTKFilesReader::DataType MutiVTKFilesReader::CheckDataInnerType()
    {
        std::ifstream infile;
        infile.open(m_fileName.toStdWString(), ios::in);
        //文件不存在
        if (!infile.is_open())
        {
            qDebug() << "Open file failed. File Name is " << m_fileName;
            infile.close();
            return DataType::UNKNOWN;
        }
        //读取文件，对第四行进行分割
        std::string str;
        int countLine = 1;
        std::vector<std::string> res;
        while (getline(infile, str))
        {
            if (4 == countLine)
            {
                CommonFunction::Stringsplit(str, " ", res);
                break;
            }
            ++countLine;
        }
        infile.close();
        //文件分割结果不符合要求
        if (res.size() != 2)
        {
            qDebug() << m_fileName << "is not supported type!(MutiVTKFilesReader)";
            return DataType::UNKNOWN;
        }
        //UNSTRUCTURED_GRID
        if (CommonFunction::trim(res[1]) == "UNSTRUCTURED_GRID")
        {
            std::cout << "File type is UNSTRUCTURED_GRID" << std::endl;
            return DataType::UNSTRUCTEDGRID;
        }//POLYDATA
        else if (CommonFunction::trim(res[1]) == "POLYDATA")
        {
            std::cout << "File type is POLYDATA" << std::endl;
            return DataType::POLYDATA;
        }
        //STRUCTURED_GRID
        else if (CommonFunction::trim(res[1]) == "STRUCTURED_GRID")
        {
            std::cout << "File type is STRUCTURED_GRID" << std::endl;
            return DataType::STRUCTEDGRID;
        }//不支持的.vtk格式
        else
        {
            std::cout << "File type is not supported type!" << std::endl;
            return DataType::UNKNOWN;
        }
        return DataType::UNKNOWN;
    }

} //namespace pst
